home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / TKERN091.ZIP / SRC / WINDOW.C < prev    next >
Text File  |  1994-03-17  |  30KB  |  1,384 lines

  1. /*
  2.  *  This file forms part of "TKERN" - "Troy's Kernel for Windows".
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #include <memory.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <errno.h>
  27. #include <sys/tfile.h>
  28. #include <sys/tdevice.h>
  29. #include <sys/tkwin.h>
  30.  
  31. static    BOOL    bRegistered = 0;
  32. extern    HINSTANCE    hInstance;
  33. extern    int    nError;
  34. extern    void    UnlockManager(void);
  35. extern    void    LockManager(void);
  36. extern    void    FlushMessages(void);
  37. extern    void    tkern_wakeup_call(void);
  38. static    int    window_destroy(HWND hWnd);
  39.  
  40. #define    SC_COPY    5000
  41. #define    SC_PASTE    5001
  42. #define    SC_COPYPASTE    5002
  43.  
  44. #define    DEF_MAXLINES    100
  45. #define    DEF_SCROLLLINES    5
  46.  
  47. struct    line
  48. {
  49.     struct    line *plNext;
  50.     struct    line *plPrev;
  51.     char    *pchLine;
  52. };
  53.  
  54. struct    per_window
  55. {
  56.     struct    line    *pw_head;
  57.     struct    line    *pw_tail;
  58.     struct    line    *pw_inhead;
  59.     struct    line    *pw_intail;
  60.     struct    line    *pw_history;
  61.     struct    line    *pw_hishead;
  62.     struct    line    *pw_histail;
  63.     int    nUnscrolledLines;
  64.     int    nHistory;
  65.     int    nHistMax;
  66.     int    nScrollLines;
  67.     int    nLines;            /* Counter so we can keep the list reasonable */
  68.     int    nLinesMax;
  69.     int    cxChar;
  70.     int    cyChar;
  71.     int    nScrollPos;
  72.     HWND    hEdit;
  73.     int    xEditStart;
  74.     POINT    ptMarkStart;
  75.     POINT    ptMarkEnd;
  76.     BOOL    bMarkValid;
  77.     BOOL    bHaveMouse;
  78.     BOOL    bProgramClosed;
  79. };
  80.  
  81. #define    ENTER_HIT    WM_USER + 1000
  82. #define    UP_HIT        WM_USER + 1001
  83. #define DOWN_HIT    WM_USER + 1002
  84.  
  85. WNDPROC    NormalEditWndProc = 0;
  86.  
  87. FARPROC    FakeEditThunk = 0;
  88.  
  89. int    far    pascal    _export
  90. FakeEditWndProc(    HWND    hWnd,
  91.             UINT    wMsg,
  92.             WPARAM    wParam,
  93.             LPARAM    lParam)
  94. {
  95.     if (wMsg == WM_KEYDOWN)
  96.     {
  97.         if (wParam == VK_UP)
  98.         {
  99.             SendMessage(GetParent(hWnd), UP_HIT, 0, 0);
  100.             return 0;
  101.         }
  102.         else if (wParam == VK_DOWN)
  103.         {
  104.             SendMessage(GetParent(hWnd), DOWN_HIT, 0, 0);
  105.             return 0;
  106.         }
  107.     }
  108.     if (wMsg == WM_CHAR)
  109.     {
  110.         if (wParam == VK_RETURN)
  111.         {
  112.             SendMessage(GetParent(hWnd), ENTER_HIT, 0, 0);
  113.             return 0;
  114.         }
  115.         else if (wParam == VK_TAB)
  116.         {
  117.             SendMessage(hWnd, EM_REPLACESEL, 0, (long) "\t");
  118.             return 0;
  119.         }
  120.     }
  121.     return (*NormalEditWndProc)(hWnd, wMsg, wParam, lParam);
  122. }
  123.  
  124. static    void
  125. MoveMark(struct per_window *pw,
  126.      int nLines)
  127. {
  128.     if (pw->bMarkValid)
  129.     {
  130.         pw->ptMarkStart.y += nLines;
  131.         pw->ptMarkEnd.y += nLines;
  132.     }
  133. }
  134.  
  135. static    void
  136. screen_to_row(    HWND    hWnd,
  137.         struct    per_window *pw,
  138.         int    x,
  139.         int    y,
  140.         int    *xOut,
  141.         int    *yOut)
  142. {
  143.     RECT    rcClient;
  144.     int    cyLastRow;
  145.     struct line *pl;
  146.     int    i, j;
  147.  
  148.     GetClientRect(hWnd, &rcClient);
  149.  
  150.     y = rcClient.bottom - y;
  151.     cyLastRow = pw->cyChar + pw->cyChar / 5 * 2;
  152.     if (y < cyLastRow)
  153.     {
  154.         *yOut = 0;
  155.     }
  156.     else
  157.     {
  158.         *yOut = (y - cyLastRow) / pw->cyChar + 1;
  159.     }
  160.  
  161.     if (*yOut > 0)
  162.         *yOut += pw->nScrollPos;
  163.  
  164.     for (i = *yOut, pl = pw->pw_tail;
  165.          i && pl;
  166.          i--, pl = pl->plPrev);
  167.  
  168.     if (!pl || !pl->pchLine)
  169.     {
  170.         *xOut = 0;
  171.         return;
  172.     }
  173.  
  174.     x = x / pw->cxChar;
  175.  
  176.     for (i = j = 0; x > j && pl->pchLine[i]; i++)
  177.     {
  178.         if (pl->pchLine[i] == '\t')
  179.             j += 8 - j % 8;
  180.         else
  181.             j++;
  182.     }
  183.     *xOut = i;
  184. }
  185.  
  186. static    void
  187. RedrawPoints(    HWND    hWnd,
  188.         struct per_window *pw,
  189.         POINT    ptStart_,
  190.         POINT    ptEnd_)
  191. {
  192.     POINT    ptStart, ptEnd;
  193.     RECT    rcRedraw;
  194.  
  195.     if (ptStart_.y > ptEnd_.y)
  196.     {
  197.         ptStart = ptStart_;
  198.         ptEnd = ptEnd_;
  199.     }
  200.     else if (ptStart_.y < ptEnd_.y)
  201.     {
  202.         ptStart = ptEnd_;
  203.         ptEnd = ptStart_;
  204.     }
  205.     else if (ptStart_.x < ptEnd_.x)
  206.     {
  207.         ptStart = ptStart_;
  208.         ptEnd = ptEnd_;
  209.     }
  210.     else
  211.     {
  212.         ptStart = ptEnd_;
  213.         ptEnd = ptStart_;
  214.     }
  215.     if (ptEnd.y > 0)
  216.     {
  217.         ptEnd.y -= pw->nScrollPos;
  218.         if (ptEnd.y < 0)
  219.             ptEnd.y = 0;
  220.     }
  221.     if (ptStart.y > 0)
  222.     {
  223.         ptStart.y -= pw->nScrollPos;
  224.         if (ptStart.y < 1)
  225.             ptStart.y = 1;
  226.     }
  227.  
  228.     if (ptStart.y < ptEnd.y)
  229.         return;
  230.     GetClientRect(hWnd, &rcRedraw);
  231.     rcRedraw.top = rcRedraw.bottom - pw->cyChar * (ptStart.y + 1) - pw->cyChar / 5 * 2;
  232.     if (ptEnd.y)
  233.         rcRedraw.bottom -= pw->cyChar * ptEnd.y + pw->cyChar / 5 * 2;
  234.     InvalidateRect(hWnd, &rcRedraw, TRUE);
  235. }
  236.  
  237. static    void
  238. MouseDown(    HWND    hWnd,
  239.         struct per_window *pw,
  240.         int    x,
  241.         int    y)
  242. {
  243.     if (pw->bMarkValid)
  244.     {
  245.         pw->bMarkValid = FALSE;
  246.         RedrawPoints(hWnd, pw, pw->ptMarkStart, pw->ptMarkEnd);
  247.     }
  248.     screen_to_row(hWnd, pw, x, y, &pw->ptMarkStart.x, &pw->ptMarkStart.y);
  249.     pw->ptMarkEnd = pw->ptMarkStart;
  250.     RedrawPoints(hWnd, pw, pw->ptMarkStart, pw->ptMarkEnd);
  251.     SetCapture(hWnd);
  252.     pw->bHaveMouse = TRUE;
  253.     pw->bMarkValid = TRUE;
  254. }
  255.  
  256. static    void
  257. MouseMove(    HWND    hWnd,
  258.         struct per_window *pw,
  259.         int    x,
  260.         int    y)
  261. {
  262.     POINT    ptTemp;
  263.  
  264.     ptTemp = pw->ptMarkEnd;
  265.     screen_to_row(hWnd, pw, x, y, &pw->ptMarkEnd.x, &pw->ptMarkEnd.y);
  266.     RedrawPoints(hWnd, pw, ptTemp, pw->ptMarkEnd);
  267. }
  268.  
  269. static    void
  270. MouseUp(struct per_window *pw)
  271. {
  272.     ReleaseCapture();
  273.     pw->bHaveMouse = FALSE;
  274. }
  275.         
  276.  
  277. static    void
  278. get_mark_coordinates(    struct    per_window *pw,
  279.             POINT    *ptOne,
  280.             POINT    *ptTwo)
  281. {
  282.     if (pw->ptMarkStart.y > pw->ptMarkEnd.y)
  283.     {
  284.         *ptOne = pw->ptMarkStart;
  285.         *ptTwo = pw->ptMarkEnd;
  286.     }
  287.     else if (pw->ptMarkStart.y < pw->ptMarkEnd.y)
  288.     {
  289.         *ptOne = pw->ptMarkEnd;
  290.         *ptTwo = pw->ptMarkStart;
  291.     }
  292.     else if (pw->ptMarkStart.x < pw->ptMarkEnd.x)
  293.     {
  294.         *ptOne = pw->ptMarkStart;
  295.         *ptTwo = pw->ptMarkEnd;
  296.     }
  297.     else
  298.     {
  299.         *ptOne = pw->ptMarkEnd;
  300.         *ptTwo = pw->ptMarkStart;
  301.     }
  302. }
  303.  
  304.  
  305. static    int
  306. is_in_mark(    int    iRow,
  307.         struct per_window *pw,
  308.         int    *iMarkBoundary1,
  309.         int    *iMarkBoundary2)
  310. {
  311.     POINT    ptStart, ptEnd;
  312.  
  313.     if (!pw->bMarkValid)
  314.         return 0;
  315.     get_mark_coordinates(pw, &ptStart, &ptEnd);
  316.     if (ptStart.y > ptEnd.y)
  317.     {
  318.         if (ptEnd.y > iRow ||
  319.             ptStart.y < iRow)
  320.             return 0;
  321.         if (ptStart.y == iRow)
  322.         {
  323.             *iMarkBoundary1 = ptStart.x;
  324.             return 1;
  325.         }
  326.         if (ptEnd.y == iRow)
  327.         {
  328.             *iMarkBoundary1 = ptEnd.x;
  329.             return 2;
  330.         }
  331.         return 3;
  332.     }
  333.     else if (ptStart.y == iRow)
  334.     {
  335.         *iMarkBoundary1 = ptStart.x;
  336.         *iMarkBoundary2 = ptEnd.x;
  337.         return 4;
  338.     }
  339.     else
  340.     {
  341.         return 0;
  342.     }
  343. }
  344.  
  345. static    void
  346. PlaceEdit(    HWND    hWnd,
  347.         struct per_window *pw)
  348. {
  349.     RECT    rcLoc;
  350.  
  351.     GetClientRect(hWnd, &rcLoc);
  352.     rcLoc.left = pw->xEditStart;
  353.     rcLoc.top = rcLoc.bottom - pw->cyChar - pw->cyChar / 5;
  354.     if (pw->hEdit)
  355.     {
  356.         MoveWindow(pw->hEdit,
  357.                 rcLoc.left, rcLoc.top,
  358.                 rcLoc.right - rcLoc.left + 1,
  359.                 rcLoc.bottom - rcLoc.top + 1,
  360.                 TRUE);
  361.     }
  362.     else
  363.     {
  364.         pw->hEdit = CreateWindow(    "EDIT",
  365.                         "",
  366.                         WS_VISIBLE |
  367.                          WS_CHILD |
  368.                          ES_AUTOHSCROLL |
  369.                          ES_LEFT,
  370.                         rcLoc.left,
  371.                         rcLoc.top,
  372.                         rcLoc.right - rcLoc.left,
  373.                         rcLoc.bottom - rcLoc.top,
  374.                         hWnd,
  375.                         (HMENU) 100,
  376.                         hInstance,
  377.                         0
  378.                     );
  379.         if (!NormalEditWndProc)
  380.         {
  381.             NormalEditWndProc = (WNDPROC)
  382.                 GetWindowLong(pw->hEdit, GWL_WNDPROC);
  383.         }
  384.         if (!FakeEditThunk)
  385.         {
  386.             FakeEditThunk = MakeProcInstance((FARPROC) FakeEditWndProc, hInstance);
  387.         }
  388.         SetWindowLong(pw->hEdit, GWL_WNDPROC, (long) FakeEditThunk);
  389.     }
  390. }
  391.  
  392. static    void
  393. PaintWindow(    HWND    hWnd,
  394.         struct per_window *pw)
  395. {
  396.     PAINTSTRUCT    ps;
  397.     TEXTMETRIC    tm;
  398.     LOGFONT        lf;
  399.     int        cyChar;
  400.     int        cyInch;
  401.     int        yLocation;
  402.     int        nRows;
  403.     RECT        rcClient;
  404.     HFONT        hFont, hOldFont;
  405.     int        iRow, iTemp, iTotal;
  406.     struct line    *pl;
  407.     LONG        xExtent, xExtent2;
  408.     BOOL        bBottom = TRUE;
  409.     int        iMarkBoundary1, iMarkBoundary2;
  410.     COLORREF    crBG, crFG, crFGHigh, crBGHigh;
  411.  
  412.     crFG = GetSysColor(COLOR_WINDOWTEXT);
  413.     crBG = GetSysColor(COLOR_WINDOW);
  414.     crFGHigh = GetS